﻿namespace UnityEditor
{
    using System;
    using System.Collections.Generic;
    using UnityEditorInternal;
    using UnityEngine;

    [CanEditMultipleObjects, CustomEditor(typeof(ProceduralMaterial))]
    internal class ProceduralMaterialInspector : MaterialEditor
    {
        private static string[] kMaxLoadBehaviorStrings = new string[] { "Do nothing", "Generate textures", "Bake and keep", "Bake and discard" };
        private static int[] kMaxLoadBehaviorValues = new int[] { 0, 1, 2, 3, 4 };
        private static string[] kMaxTextureSizeStrings = new string[] { "32", "64", "128", "256", "512", "1024", "2048" };
        private static int[] kMaxTextureSizeValues = new int[] { 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800 };
        private static Dictionary<ProceduralMaterial, float> m_GeneratingSince = new Dictionary<ProceduralMaterial, float>();
        private static SubstanceImporter m_Importer = null;
        private string m_LastGroup;
        private static ProceduralMaterial m_Material = null;
        private bool m_MightHaveModified;
        protected List<ProceduralPlatformSetting> m_PlatformSettings;
        private Vector2 m_ScrollPos = new Vector2();
        private static Shader m_Shader = null;
        private bool m_ShowTexturesSection;
        private Styles m_Styles;

        internal void Apply()
        {
            foreach (ProceduralPlatformSetting setting in this.m_PlatformSettings)
            {
                setting.Apply();
            }
        }

        public override void Awake()
        {
            base.Awake();
            this.m_ShowTexturesSection = EditorPrefs.GetBool("ProceduralShowTextures", false);
        }

        public void BuildTargetList()
        {
            List<BuildPlayerWindow.BuildPlatform> validPlatforms = BuildPlayerWindow.GetValidPlatforms();
            this.m_PlatformSettings = new List<ProceduralPlatformSetting>();
            this.m_PlatformSettings.Add(new ProceduralPlatformSetting(base.targets, string.Empty, BuildTarget.StandaloneWindows, null));
            foreach (BuildPlayerWindow.BuildPlatform platform in validPlatforms)
            {
                this.m_PlatformSettings.Add(new ProceduralPlatformSetting(base.targets, platform.name, platform.DefaultTarget, platform.smallIcon));
            }
        }

        internal static void DoObjectPingField(Rect position, Rect dropRect, int id, UnityEngine.Object obj, System.Type objType)
        {
            Event current = Event.current;
            EventType rawType = current.type;
            if ((!GUI.enabled && GUIClip.enabled) && (Event.current.rawType == EventType.MouseDown))
            {
                rawType = Event.current.rawType;
            }
            switch (rawType)
            {
                case EventType.MouseDown:
                    if ((Event.current.button == 0) && position.Contains(Event.current.mousePosition))
                    {
                        UnityEngine.Object gameObject = obj;
                        Component component = gameObject as Component;
                        if (component != null)
                        {
                            gameObject = component.gameObject;
                        }
                        if (Event.current.clickCount == 1)
                        {
                            GUIUtility.keyboardControl = id;
                            if (gameObject != null)
                            {
                                EditorGUIUtility.PingObject(gameObject);
                            }
                            current.Use();
                        }
                        else if (Event.current.clickCount == 2)
                        {
                            if (gameObject != null)
                            {
                                AssetDatabase.OpenAsset(gameObject);
                                GUIUtility.ExitGUI();
                            }
                            current.Use();
                        }
                    }
                    break;

                case EventType.Repaint:
                {
                    GUIContent content = EditorGUIUtility.ObjectContent(obj, objType);
                    if (!EditorGUIUtility.lookLikeInspector && EditorGUIUtility.HasObjectThumbnail(objType))
                    {
                        GUIStyle objectFieldThumb = EditorStyles.objectFieldThumb;
                        objectFieldThumb.Draw(position, GUIContent.none, id, DragAndDrop.activeControlID == id);
                        if (obj != null)
                        {
                            EditorGUI.DrawPreviewTexture(objectFieldThumb.padding.Remove(position), content.image);
                        }
                        else
                        {
                            (objectFieldThumb.name + "Overlay").Draw(position, content, id);
                        }
                    }
                    else
                    {
                        EditorStyles.objectField.Draw(position, content, id, DragAndDrop.activeControlID == id);
                    }
                    break;
                }
            }
        }

        [UnityEditor.MenuItem("CONTEXT/ProceduralMaterial/Export Bitmaps", false)]
        public static void ExportBitmaps(MenuCommand command)
        {
            m_Importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(command.context)) as SubstanceImporter;
            m_Importer.ExportBitmaps(command.context as ProceduralMaterial);
        }

        private void GeneratedTextures()
        {
            string content = "Generated Textures";
            if (ShowIsGenerating(base.target as ProceduralMaterial))
            {
                content = content + " (Generating...)";
            }
            GUI.changed = false;
            this.m_ShowTexturesSection = EditorGUILayout.Foldout(this.m_ShowTexturesSection, content);
            if (GUI.changed)
            {
                EditorPrefs.SetBool("ProceduralShowTextures", this.m_ShowTexturesSection);
                GUI.changed = false;
            }
            if (this.m_ShowTexturesSection)
            {
                this.ShowProceduralTexturesGUI(m_Material);
                this.ShowGeneratedTexturesGUI(m_Material);
                if (m_Importer != null)
                {
                    if (this.HasProceduralTextureProperties(m_Material))
                    {
                        this.OffsetScaleGUI(m_Material);
                    }
                    EditorGUI.BeginDisabledGroup(EditorApplication.isPlaying);
                    this.ShowTextureSizeGUI();
                    EditorGUI.EndDisabledGroup();
                }
            }
        }

        public override string GetInfoString()
        {
            ProceduralMaterial target = base.target as ProceduralMaterial;
            if (target.mainTexture == null)
            {
                return string.Empty;
            }
            return (target.mainTexture.width + "x" + target.mainTexture.height);
        }

        internal bool HasModified()
        {
            foreach (ProceduralPlatformSetting setting in this.m_PlatformSettings)
            {
                if (setting.HasChanged())
                {
                    return true;
                }
            }
            return false;
        }

        public bool HasProceduralTextureProperties(Material material)
        {
            Shader s = material.shader;
            int propertyCount = ShaderUtil.GetPropertyCount(s);
            for (int i = 0; i < propertyCount; i++)
            {
                if (ShaderUtil.GetPropertyType(s, i) == ShaderUtil.ShaderPropertyType.TexEnv)
                {
                    string propertyName = ShaderUtil.GetPropertyName(s, i);
                    Texture tex = material.GetTexture(propertyName);
                    if (SubstanceImporter.IsProceduralTextureSlot(material, tex, propertyName))
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        private void InputGUI(ProceduralPropertyDescription input)
        {
            float proceduralFloat;
            float num3;
            if (input.group != this.m_LastGroup)
            {
                GUILayout.Label(input.group, EditorStyles.label, new GUILayoutOption[0]);
                this.m_LastGroup = input.group;
            }
            int indentLevel = EditorGUI.indentLevel;
            if (input.group != string.Empty)
            {
                EditorGUI.indentLevel++;
            }
            ProceduralPropertyType type = input.type;
            string label = ObjectNames.NicifyVariableName(input.name);
            switch (type)
            {
                case ProceduralPropertyType.Boolean:
                {
                    bool proceduralBoolean = m_Material.GetProceduralBoolean(input.name);
                    bool flag2 = proceduralBoolean;
                    proceduralBoolean = EditorGUILayout.Toggle(label, proceduralBoolean, new GUILayoutOption[0]);
                    if (proceduralBoolean != flag2)
                    {
                        m_Material.SetProceduralBoolean(input.name, proceduralBoolean);
                    }
                    goto Label_040B;
                }
                case ProceduralPropertyType.Float:
                {
                    proceduralFloat = m_Material.GetProceduralFloat(input.name);
                    num3 = proceduralFloat;
                    if (!input.hasRange)
                    {
                        proceduralFloat = EditorGUILayout.FloatField(label, proceduralFloat, new GUILayoutOption[0]);
                        break;
                    }
                    float minimum = input.minimum;
                    float maximum = input.maximum;
                    proceduralFloat = EditorGUILayout.Slider(label, proceduralFloat, minimum, maximum, new GUILayoutOption[0]);
                    break;
                }
                case ProceduralPropertyType.Vector2:
                case ProceduralPropertyType.Vector3:
                case ProceduralPropertyType.Vector4:
                {
                    int num6 = (type != ProceduralPropertyType.Vector2) ? ((type != ProceduralPropertyType.Vector3) ? 4 : 3) : 2;
                    Vector4 proceduralVector = m_Material.GetProceduralVector(input.name);
                    Vector4 vector2 = proceduralVector;
                    if (!input.hasRange)
                    {
                        switch (num6)
                        {
                            case 2:
                                proceduralVector = EditorGUILayout.Vector2Field(label, (Vector2) proceduralVector, new GUILayoutOption[0]);
                                break;

                            case 3:
                                proceduralVector = EditorGUILayout.Vector3Field(label, (Vector3) proceduralVector, new GUILayoutOption[0]);
                                break;

                            case 4:
                                proceduralVector = EditorGUILayout.Vector4Field(label, proceduralVector, new GUILayoutOption[0]);
                                break;
                        }
                    }
                    else
                    {
                        float leftValue = input.minimum;
                        float rightValue = input.maximum;
                        EditorGUILayout.BeginVertical(new GUILayoutOption[0]);
                        GUILayout.Label(label, new GUILayoutOption[0]);
                        EditorGUI.indentLevel++;
                        for (int i = 0; i < num6; i++)
                        {
                            proceduralVector[i] = EditorGUILayout.Slider(this.m_Styles.coordNames[i], proceduralVector[i], leftValue, rightValue, new GUILayoutOption[0]);
                        }
                        EditorGUI.indentLevel--;
                        EditorGUILayout.EndVertical();
                    }
                    if (proceduralVector != vector2)
                    {
                        m_Material.SetProceduralVector(input.name, proceduralVector);
                    }
                    goto Label_040B;
                }
                case ProceduralPropertyType.Color3:
                case ProceduralPropertyType.Color4:
                {
                    Color proceduralColor = m_Material.GetProceduralColor(input.name);
                    Color color2 = proceduralColor;
                    proceduralColor = EditorGUILayout.ColorField(label, proceduralColor, new GUILayoutOption[0]);
                    if (proceduralColor != color2)
                    {
                        m_Material.SetProceduralColor(input.name, proceduralColor);
                    }
                    goto Label_040B;
                }
                case ProceduralPropertyType.Enum:
                {
                    int proceduralEnum = m_Material.GetProceduralEnum(input.name);
                    int num11 = proceduralEnum;
                    string[] enumOptions = input.enumOptions;
                    proceduralEnum = EditorGUILayout.Popup(label, proceduralEnum, enumOptions, new GUILayoutOption[0]);
                    if (proceduralEnum != num11)
                    {
                        m_Material.SetProceduralEnum(input.name, proceduralEnum);
                    }
                    goto Label_040B;
                }
                case ProceduralPropertyType.Texture:
                {
                    Texture2D proceduralTexture = m_Material.GetProceduralTexture(input.name);
                    Texture2D textured2 = proceduralTexture;
                    EditorGUILayout.BeginHorizontal(new GUILayoutOption[0]);
                    GUILayout.Label(label, new GUILayoutOption[0]);
                    GUILayout.FlexibleSpace();
                    GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.ExpandWidth(false) };
                    Rect position = GUILayoutUtility.GetRect((float) 64f, (float) 64f, options);
                    proceduralTexture = EditorGUI.DoObjectField(position, position, EditorGUI.GetControlID(0x3042, EditorGUIUtility.native, position), proceduralTexture, typeof(Texture2D), null, null, false) as Texture2D;
                    EditorGUILayout.EndHorizontal();
                    if (proceduralTexture != textured2)
                    {
                        m_Material.SetProceduralTexture(input.name, proceduralTexture);
                    }
                    goto Label_040B;
                }
                default:
                    goto Label_040B;
            }
            if (proceduralFloat != num3)
            {
                m_Material.SetProceduralFloat(input.name, proceduralFloat);
            }
        Label_040B:
            EditorGUI.indentLevel = indentLevel;
        }

        private void InputHSLGUI(ProceduralPropertyDescription hInput, ProceduralPropertyDescription sInput, ProceduralPropertyDescription lInput)
        {
            EditorGUILayout.BeginVertical(new GUILayoutOption[0]);
            GUILayout.Label(this.m_Styles.hslContent, EditorStyles.label, new GUILayoutOption[0]);
            EditorGUI.indentLevel++;
            this.InputGUI(hInput);
            this.InputGUI(sInput);
            this.InputGUI(lInput);
            EditorGUI.indentLevel--;
            EditorGUILayout.EndVertical();
        }

        protected void InputOptions(ProceduralMaterial material)
        {
            this.InputsGUI();
            if (GUI.changed)
            {
                UnityEngine.Object[] objectsToUndo = new UnityEngine.Object[] { material, m_Importer };
                Undo.RegisterUndo(material, objectsToUndo, "Modify " + material.name + " Procedural Property");
                material.RebuildTextures();
            }
        }

        private void InputSeedGUI(ProceduralPropertyDescription input)
        {
            float proceduralFloat = m_Material.GetProceduralFloat(input.name);
            float num2 = proceduralFloat;
            Rect position = GUILayoutUtility.GetRect(GUIContent.none, EditorStyles.popup);
            proceduralFloat = this.RandomIntField(position, this.m_Styles.randomSeedContent, (int) proceduralFloat, 0, 0x270f);
            if (proceduralFloat != num2)
            {
                m_Material.SetProceduralFloat(input.name, proceduralFloat);
            }
        }

        public void InputsGUI()
        {
            ProceduralPropertyDescription[] proceduralPropertyDescriptions = m_Material.GetProceduralPropertyDescriptions();
            ProceduralPropertyDescription hInput = null;
            ProceduralPropertyDescription sInput = null;
            ProceduralPropertyDescription lInput = null;
            this.m_LastGroup = string.Empty;
            for (int i = 0; i < proceduralPropertyDescriptions.Length; i++)
            {
                ProceduralPropertyDescription input = proceduralPropertyDescriptions[i];
                if (input.name != "$outputsize")
                {
                    if (input.name == "$randomseed")
                    {
                        this.InputSeedGUI(input);
                    }
                    else if ((input.name == "Hue_Shift") && (input.group == string.Empty))
                    {
                        hInput = input;
                    }
                    else if ((input.name == "Saturation") && (input.group == string.Empty))
                    {
                        sInput = input;
                    }
                    else if ((input.name == "Luminosity") && (input.group == string.Empty))
                    {
                        lInput = input;
                    }
                    else if ((input.name.Length <= 0) || (input.name[0] != '$'))
                    {
                        this.InputGUI(input);
                    }
                }
            }
            if ((((hInput != null) && (sInput != null)) && ((lInput != null) && (hInput.type == ProceduralPropertyType.Float))) && ((sInput.type == ProceduralPropertyType.Float) && (lInput.type == ProceduralPropertyType.Float)))
            {
                this.InputHSLGUI(hInput, sInput, lInput);
            }
            else
            {
                if (hInput != null)
                {
                    this.InputGUI(hInput);
                }
                if (sInput != null)
                {
                    this.InputGUI(sInput);
                }
                if (lInput != null)
                {
                    this.InputGUI(lInput);
                }
            }
        }

        internal override bool IsEnabled()
        {
            return base.IsOpenForEdit();
        }

        protected void OffsetScaleGUI(ProceduralMaterial material)
        {
            if ((m_Importer != null) && (base.targets.Length <= 1))
            {
                GUILayoutOption option = GUILayout.Width(10f);
                GUILayoutOption option2 = GUILayout.MinWidth(32f);
                GUILayout.BeginHorizontal(new GUILayoutOption[0]);
                EditorGUILayout.BeginVertical(new GUILayoutOption[0]);
                Vector2 materialScale = m_Importer.GetMaterialScale(material);
                Vector2 vector2 = materialScale;
                Vector2 materialOffset = m_Importer.GetMaterialOffset(material);
                Vector2 vector4 = materialOffset;
                GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.ExpandWidth(true) };
                GUILayout.BeginHorizontal(options);
                GUILayout.Space(8f);
                GUILayout.FlexibleSpace();
                GUILayout.BeginVertical(new GUILayoutOption[0]);
                GUILayoutOption[] optionArray2 = new GUILayoutOption[] { option };
                GUILayout.Label(string.Empty, EditorStyles.miniLabel, optionArray2);
                GUILayoutOption[] optionArray3 = new GUILayoutOption[] { option };
                GUILayout.Label("x", EditorStyles.miniLabel, optionArray3);
                GUILayoutOption[] optionArray4 = new GUILayoutOption[] { option };
                GUILayout.Label("y", EditorStyles.miniLabel, optionArray4);
                GUILayout.EndVertical();
                GUILayout.BeginVertical(new GUILayoutOption[0]);
                GUILayout.Label("Tiling", EditorStyles.miniLabel, new GUILayoutOption[0]);
                GUILayoutOption[] optionArray5 = new GUILayoutOption[] { option2 };
                materialScale.x = EditorGUILayout.FloatField(materialScale.x, EditorStyles.miniTextField, optionArray5);
                GUILayoutOption[] optionArray6 = new GUILayoutOption[] { option2 };
                materialScale.y = EditorGUILayout.FloatField(materialScale.y, EditorStyles.miniTextField, optionArray6);
                GUILayout.EndVertical();
                GUILayout.BeginVertical(new GUILayoutOption[0]);
                GUILayout.Label("Offset", EditorStyles.miniLabel, new GUILayoutOption[0]);
                GUILayoutOption[] optionArray7 = new GUILayoutOption[] { option2 };
                materialOffset.x = EditorGUILayout.FloatField(materialOffset.x, EditorStyles.miniTextField, optionArray7);
                GUILayoutOption[] optionArray8 = new GUILayoutOption[] { option2 };
                materialOffset.y = EditorGUILayout.FloatField(materialOffset.y, EditorStyles.miniTextField, optionArray8);
                GUILayout.EndVertical();
                GUILayout.EndHorizontal();
                if ((vector2 != materialScale) || (vector4 != materialOffset))
                {
                    UnityEngine.Object[] objectsToUndo = new UnityEngine.Object[] { material, m_Importer };
                    Undo.RegisterUndo(material, objectsToUndo, "Modify " + material.name + "'s Tiling/Offset");
                    m_Importer.SetMaterialOffset(material, materialOffset);
                    m_Importer.SetMaterialScale(material, materialScale);
                }
                GUILayout.EndVertical();
                GUILayout.EndHorizontal();
            }
        }

        internal override void OnAssetStoreInspectorGUI()
        {
            if (this.m_Styles == null)
            {
                this.m_Styles = new Styles();
            }
            ProceduralMaterial target = base.target as ProceduralMaterial;
            if (m_Material != target)
            {
                m_Material = target;
                m_Shader = target.shader;
            }
            this.ProceduralProperties();
            GUILayout.Space(15f);
            this.GeneratedTextures();
        }

        public override void OnDisable()
        {
            if (this.m_MightHaveModified)
            {
                if (!EditorApplication.isPlaying && !InternalEditorUtility.ignoreInspectorChanges)
                {
                    this.ReimportSubstances();
                }
                if (!EditorApplication.isPlaying)
                {
                    ProceduralMaterial.substanceProcessorUsage = ProceduralProcessorUsage.One;
                }
            }
            EditorApplication.undoRedoPerformed = (EditorApplication.CallbackFunction) Delegate.Remove(EditorApplication.undoRedoPerformed, new EditorApplication.CallbackFunction(this.UndoRedoPerformed));
            base.OnDisable();
        }

        public override void OnEnable()
        {
            base.OnEnable();
            if (!EditorApplication.isPlaying)
            {
                ProceduralMaterial.substanceProcessorUsage = ProceduralProcessorUsage.All;
            }
            EditorApplication.undoRedoPerformed = (EditorApplication.CallbackFunction) Delegate.Combine(EditorApplication.undoRedoPerformed, new EditorApplication.CallbackFunction(this.UndoRedoPerformed));
        }

        internal override void OnHeaderTitleGUI(Rect titleRect, string header)
        {
            ProceduralMaterial target = base.target as ProceduralMaterial;
            m_Importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(base.target)) as SubstanceImporter;
            if (m_Importer != null)
            {
                string name = target.name;
                name = EditorGUI.DelayedTextField(titleRect, name, null, EditorStyles.textField);
                if (name != target.name)
                {
                    if (m_Importer.RenameMaterial(target, name))
                    {
                        AssetDatabase.ImportAsset(m_Importer.assetPath, ImportAssetOptions.ForceUncompressedImport);
                        GUIUtility.ExitGUI();
                    }
                    else
                    {
                        name = target.name;
                    }
                }
            }
        }

        public override void OnInspectorGUI()
        {
            this.m_MightHaveModified = true;
            if (this.m_Styles == null)
            {
                this.m_Styles = new Styles();
            }
            ProceduralMaterial target = base.target as ProceduralMaterial;
            m_Importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(base.target)) as SubstanceImporter;
            if (m_Importer == null)
            {
                GUILayout.Label("Invalid Procedural Material", new GUILayoutOption[0]);
            }
            else
            {
                if (m_Material != target)
                {
                    m_Material = target;
                    m_Shader = target.shader;
                }
                if (base.m_IsVisible && (target.shader != null))
                {
                    if (m_Shader != target.shader)
                    {
                        m_Shader = target.shader;
                        foreach (ProceduralMaterial material2 in base.targets)
                        {
                            (AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(material2)) as SubstanceImporter).OnShaderModified(material2);
                        }
                    }
                    if (base.PropertiesGUI())
                    {
                        m_Shader = target.shader;
                        foreach (ProceduralMaterial material3 in base.targets)
                        {
                            (AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(material3)) as SubstanceImporter).OnShaderModified(material3);
                        }
                        base.PropertiesChanged();
                    }
                    GUI.changed = false;
                    GUILayout.Space(5f);
                    this.ProceduralProperties();
                    GUILayout.Space(15f);
                    this.GeneratedTextures();
                }
            }
        }

        public override void OnPreviewGUI(Rect r, GUIStyle background)
        {
            base.OnPreviewGUI(r, background);
            if (ShowIsGenerating(base.target as ProceduralMaterial) && (r.width > 50f))
            {
                EditorGUI.DropShadowLabel(new Rect(r.x, r.y, r.width, 20f), "Generating...");
            }
        }

        private void ProceduralProperties()
        {
            GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.ExpandWidth(true) };
            GUILayout.Label("Procedural Properties", EditorStyles.boldLabel, options);
            foreach (ProceduralMaterial material in base.targets)
            {
                if (material.isProcessing)
                {
                    base.Repaint();
                    SceneView.RepaintAll();
                    GameView.RepaintAll();
                    break;
                }
            }
            if (base.targets.Length > 1)
            {
                GUILayout.Label("Procedural properties do not support multi-editing.", EditorStyles.wordWrappedLabel, new GUILayoutOption[0]);
            }
            else
            {
                Rect rect = GUILayoutUtility.GetRect((float) 10f, (float) 0f);
                EditorGUIUtility.LookLikeControls(Mathf.Min((float) (rect.width - 146f), (float) (rect.width * 0.5f)), 40f);
                if (m_Importer != null)
                {
                    if (!ProceduralMaterial.isSupported)
                    {
                        GUILayoutOption[] optionArray2 = new GUILayoutOption[] { GUILayout.ExpandWidth(true) };
                        GUILayout.Label("Procedural Materials are not supported on " + EditorUserBuildSettings.activeBuildTarget + ". Textures will be baked.", EditorStyles.helpBox, optionArray2);
                    }
                    EditorGUI.BeginDisabledGroup(EditorApplication.isPlaying);
                    bool generated = EditorGUILayout.Toggle(this.m_Styles.generateAllOutputsContent, m_Importer.GetGenerateAllOutputs(m_Material), new GUILayoutOption[0]);
                    if (generated != m_Importer.GetGenerateAllOutputs(m_Material))
                    {
                        m_Importer.SetGenerateAllOutputs(m_Material, generated);
                    }
                    EditorGUI.EndDisabledGroup();
                    if (m_Material.HasProceduralProperty("$time"))
                    {
                        int num2 = EditorGUILayout.IntField(this.m_Styles.animatedContent, m_Importer.GetAnimationUpdateRate(m_Material), new GUILayoutOption[0]);
                        if (num2 != m_Importer.GetAnimationUpdateRate(m_Material))
                        {
                            m_Importer.SetAnimationUpdateRate(m_Material, num2);
                        }
                    }
                }
                this.InputOptions(m_Material);
            }
        }

        internal int RandomIntField(Rect position, int val, int min, int max)
        {
            position.width = (position.width - EditorGUI.kNumberW) - 5f;
            if (GUI.Button(position, this.m_Styles.randomizeButtonContent, EditorStyles.miniButton))
            {
                val = UnityEngine.Random.Range(min, max + 1);
                GUI.changed = true;
            }
            position.x += position.width + 5f;
            position.width = EditorGUI.kNumberW;
            val = Mathf.Clamp(EditorGUI.IntField(position, val), min, max);
            return val;
        }

        internal int RandomIntField(Rect position, GUIContent label, int val, int min, int max)
        {
            position = EditorGUI.PrefixLabel(position, 0x965572, label);
            return this.RandomIntField(position, val, min, max);
        }

        private void ReimportSubstances()
        {
            string[] strArray = new string[base.targets.GetLength(0)];
            int num = 0;
            foreach (ProceduralMaterial material in base.targets)
            {
                strArray[num++] = AssetDatabase.GetAssetPath(material);
            }
            for (int i = 0; i < num; i++)
            {
                SubstanceImporter atPath = AssetImporter.GetAtPath(strArray[i]) as SubstanceImporter;
                if ((atPath != null) && EditorUtility.IsDirty(atPath.GetInstanceID()))
                {
                    AssetDatabase.ImportAsset(strArray[i], ImportAssetOptions.ForceUncompressedImport);
                }
            }
        }

        [UnityEditor.MenuItem("CONTEXT/ProceduralMaterial/Reset", false, -100)]
        public static void ResetSubstance(MenuCommand command)
        {
            m_Importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(command.context)) as SubstanceImporter;
            m_Importer.ResetMaterial(command.context as ProceduralMaterial);
        }

        internal void ResetValues()
        {
            this.BuildTargetList();
            if (this.HasModified())
            {
                Debug.LogError("Impossible");
            }
        }

        private void ShowAlphaSourceGUI(ProceduralMaterial material, ProceduralTexture tex, Rect rect)
        {
            if (m_Importer != null)
            {
                EditorGUI.BeginDisabledGroup(EditorApplication.isPlaying);
                if (tex.GetProceduralOutputType() != ProceduralOutputType.Normal)
                {
                    string[] displayedOptions = new string[] { "Source (A)", "Diffuse (A)", "Normal (A)", "Height (A)", "Emissive (A)", "Specular (A)", "Opacity (A)" };
                    int textureAlphaSource = (int) m_Importer.GetTextureAlphaSource(material, tex.name);
                    EditorGUILayout.Space();
                    EditorGUILayout.Space();
                    textureAlphaSource = EditorGUI.Popup(rect, textureAlphaSource, displayedOptions);
                    if (GUI.changed)
                    {
                        UnityEngine.Object[] objectsToUndo = new UnityEngine.Object[] { material, m_Importer };
                        Undo.RegisterUndo(material, objectsToUndo, "Modify " + material.name + "'s Alpha Modifier");
                        m_Importer.SetTextureAlphaSource(material, tex.name, (ProceduralOutputType) textureAlphaSource);
                        GUI.changed = false;
                    }
                }
                EditorGUI.EndDisabledGroup();
            }
        }

        protected void ShowGeneratedTexturesGUI(ProceduralMaterial material)
        {
            if ((base.targets.Length <= 1) && ((m_Importer == null) || m_Importer.GetGenerateAllOutputs(m_Material)))
            {
                GUIStyle style = "ObjectPickerResultsGridLabel";
                GUI.changed = false;
                EditorGUILayout.Space();
                GUILayout.FlexibleSpace();
                GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.Height(((64f + style.fixedHeight) + style.fixedHeight) + 16f) };
                this.m_ScrollPos = EditorGUILayout.BeginScrollView(this.m_ScrollPos, options);
                EditorGUILayout.BeginHorizontal(new GUILayoutOption[0]);
                GUILayout.Space(4f);
                float pixels = 10f;
                bool flag = true;
                Texture[] generatedTextures = material.GetGeneratedTextures();
                for (int i = 0; i < generatedTextures.Length; i++)
                {
                    ProceduralTexture texture = generatedTextures[i] as ProceduralTexture;
                    if (texture != null)
                    {
                        if (flag)
                        {
                            flag = false;
                        }
                        else
                        {
                            GUILayout.Space(pixels);
                        }
                        GUILayoutOption[] optionArray2 = new GUILayoutOption[] { GUILayout.Height((64f + style.fixedHeight) + 8f) };
                        GUILayout.BeginVertical(optionArray2);
                        Rect position = GUILayoutUtility.GetRect((float) 64f, (float) 64f);
                        DoObjectPingField(position, position, EditorGUI.GetControlID(0x3042, EditorGUIUtility.native, position), texture, typeof(Texture));
                        position.y = position.yMax + 2f;
                        position.height = style.fixedHeight;
                        this.ShowAlphaSourceGUI(material, texture, position);
                        position.y = position.yMax + 2f;
                        position.width += pixels;
                        GUILayout.EndVertical();
                        GUILayout.FlexibleSpace();
                    }
                }
                GUILayout.Space(4f);
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.EndScrollView();
            }
        }

        public static bool ShowIsGenerating(ProceduralMaterial mat)
        {
            if (!m_GeneratingSince.ContainsKey(mat))
            {
                m_GeneratingSince[mat] = 0f;
            }
            if (mat.isProcessing)
            {
                return (Time.realtimeSinceStartup > (m_GeneratingSince[mat] + 0.4f));
            }
            m_GeneratingSince[mat] = Time.realtimeSinceStartup;
            return false;
        }

        protected void ShowProceduralTexturesGUI(ProceduralMaterial material)
        {
            if (base.targets.Length <= 1)
            {
                GUI.changed = false;
                EditorGUILayout.Space();
                Shader s = material.shader;
                if (s != null)
                {
                    EditorGUILayout.BeginHorizontal(new GUILayoutOption[0]);
                    GUILayout.Space(4f);
                    GUILayout.FlexibleSpace();
                    float pixels = 10f;
                    bool flag = true;
                    for (int i = 0; i < ShaderUtil.GetPropertyCount(s); i++)
                    {
                        if (ShaderUtil.GetPropertyType(s, i) != ShaderUtil.ShaderPropertyType.TexEnv)
                        {
                            continue;
                        }
                        string propertyName = ShaderUtil.GetPropertyName(s, i);
                        Texture tex = material.GetTexture(propertyName);
                        if (SubstanceImporter.IsProceduralTextureSlot(material, tex, propertyName))
                        {
                            System.Type type;
                            string propertyDescription = ShaderUtil.GetPropertyDescription(s, i);
                            switch (ShaderUtil.GetTexDim(s, i))
                            {
                                case ShaderUtil.ShaderPropertyTexDim.TexDim2D:
                                    type = typeof(Texture);
                                    break;

                                case ShaderUtil.ShaderPropertyTexDim.TexDim3D:
                                    type = typeof(Texture3D);
                                    break;

                                case ShaderUtil.ShaderPropertyTexDim.TexDimCUBE:
                                    type = typeof(Cubemap);
                                    break;

                                case ShaderUtil.ShaderPropertyTexDim.TexDimRECT:
                                    type = typeof(Texture);
                                    break;

                                case ShaderUtil.ShaderPropertyTexDim.TexDimAny:
                                    type = typeof(Texture);
                                    break;

                                default:
                                    type = null;
                                    break;
                            }
                            ShaderUtil.CheckNoTexturePropertyAndRebuild(material, s, i);
                            GUIStyle style = "ObjectPickerResultsGridLabel";
                            if (flag)
                            {
                                flag = false;
                            }
                            else
                            {
                                GUILayout.Space(pixels);
                            }
                            GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.Height(((72f + style.fixedHeight) + style.fixedHeight) + 8f) };
                            GUILayout.BeginVertical(options);
                            Rect position = GUILayoutUtility.GetRect((float) 72f, (float) 72f);
                            DoObjectPingField(position, position, EditorGUI.GetControlID(0x3042, EditorGUIUtility.native, position), tex, type);
                            position.y = position.yMax + 2f;
                            position.height = style.fixedHeight;
                            this.ShowAlphaSourceGUI(material, tex as ProceduralTexture, position);
                            position.y = position.yMax + 2f;
                            position.width += pixels;
                            position.height = style.fixedHeight;
                            GUI.Label(position, propertyDescription, style);
                            GUILayout.EndVertical();
                            GUILayout.FlexibleSpace();
                        }
                    }
                    GUILayout.Space(4f);
                    EditorGUILayout.EndHorizontal();
                    GUILayout.FlexibleSpace();
                }
            }
        }

        public void ShowTextureSizeGUI()
        {
            if (this.m_PlatformSettings == null)
            {
                this.BuildTargetList();
            }
            this.TextureSizeGUI();
        }

        protected void TextureSizeGUI()
        {
            int num = EditorGUILayout.BeginPlatformGrouping(BuildPlayerWindow.GetValidPlatforms().ToArray(), this.m_Styles.defaultPlatform);
            ProceduralPlatformSetting setting = this.m_PlatformSettings[num + 1];
            ProceduralPlatformSetting setting2 = setting;
            bool flag = true;
            if (setting.name != string.Empty)
            {
                GUI.changed = false;
                flag = GUILayout.Toggle(setting.overridden, "Override for " + setting.name, new GUILayoutOption[0]);
                if (GUI.changed)
                {
                    if (flag)
                    {
                        setting.SetOverride(this.m_PlatformSettings[0]);
                    }
                    else
                    {
                        setting.ClearOverride(this.m_PlatformSettings[0]);
                    }
                }
            }
            EditorGUI.BeginDisabledGroup(!flag);
            GUI.changed = false;
            setting2.maxTextureWidth = EditorGUILayout.IntPopup(this.m_Styles.targetWidth.text, setting2.maxTextureWidth, kMaxTextureSizeStrings, kMaxTextureSizeValues, new GUILayoutOption[0]);
            setting2.maxTextureHeight = EditorGUILayout.IntPopup(this.m_Styles.targetHeight.text, setting2.maxTextureHeight, kMaxTextureSizeStrings, kMaxTextureSizeValues, new GUILayoutOption[0]);
            if (GUI.changed && setting2.isDefault)
            {
                foreach (ProceduralPlatformSetting setting3 in this.m_PlatformSettings)
                {
                    if (!setting3.isDefault && !setting3.overridden)
                    {
                        setting3.maxTextureWidth = setting2.maxTextureWidth;
                        setting3.maxTextureHeight = setting2.maxTextureHeight;
                    }
                }
            }
            GUI.changed = false;
            int textureFormat = setting2.textureFormat;
            if ((textureFormat < 0) || (textureFormat > 1))
            {
                Debug.LogError("Invalid TextureFormat");
            }
            textureFormat = EditorGUILayout.Popup(this.m_Styles.textureFormat, textureFormat, this.m_Styles.textureFormatOptions, new GUILayoutOption[0]);
            if (GUI.changed)
            {
                setting2.textureFormat = textureFormat;
                if (setting2.isDefault)
                {
                    foreach (ProceduralPlatformSetting setting4 in this.m_PlatformSettings)
                    {
                        if (!setting4.isDefault && !setting4.overridden)
                        {
                            setting4.textureFormat = setting2.textureFormat;
                        }
                    }
                }
            }
            GUI.changed = false;
            setting2.m_LoadBehavior = EditorGUILayout.IntPopup(this.m_Styles.loadBehavior.text, setting2.m_LoadBehavior, kMaxLoadBehaviorStrings, kMaxLoadBehaviorValues, new GUILayoutOption[0]);
            if (GUI.changed && setting2.isDefault)
            {
                foreach (ProceduralPlatformSetting setting5 in this.m_PlatformSettings)
                {
                    if (!setting5.isDefault && !setting5.overridden)
                    {
                        setting5.m_LoadBehavior = setting2.m_LoadBehavior;
                    }
                }
            }
            GUI.changed = false;
            GUILayout.Space(5f);
            EditorGUI.BeginDisabledGroup(!this.HasModified());
            GUILayout.BeginHorizontal(new GUILayoutOption[0]);
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Revert", new GUILayoutOption[0]))
            {
                this.ResetValues();
            }
            if (GUILayout.Button("Apply", new GUILayoutOption[0]))
            {
                this.Apply();
                this.ReimportSubstances();
                this.ResetValues();
            }
            GUILayout.EndHorizontal();
            EditorGUI.EndDisabledGroup();
            GUILayout.Space(5f);
            EditorGUILayout.EndPlatformGrouping();
            EditorGUI.EndDisabledGroup();
        }

        private UnityEngine.Object TextureValidator(UnityEngine.Object[] references, System.Type objType, SerializedProperty property)
        {
            foreach (UnityEngine.Object obj2 in references)
            {
                Texture texture = obj2 as Texture;
                if (texture != null)
                {
                    return texture;
                }
            }
            return null;
        }

        public override void UndoRedoPerformed()
        {
            base.UndoRedoPerformed();
            if (m_Material != null)
            {
                m_Material.RebuildTexturesImmediately();
            }
            base.Repaint();
        }

        [Serializable]
        protected class ProceduralPlatformSetting
        {
            public Texture2D icon;
            public int m_LoadBehavior;
            public bool m_Overridden;
            public int m_TextureFormat;
            public int maxTextureHeight;
            public int maxTextureWidth;
            public string name;
            public BuildTarget target;
            private UnityEngine.Object[] targets;

            public ProceduralPlatformSetting(UnityEngine.Object[] objects, string _name, BuildTarget _target, Texture2D _icon)
            {
                this.targets = objects;
                this.m_Overridden = false;
                this.target = _target;
                this.name = _name;
                this.icon = _icon;
                this.m_Overridden = false;
                if (this.name != string.Empty)
                {
                    foreach (ProceduralMaterial material in this.targets)
                    {
                        SubstanceImporter atPath = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(material)) as SubstanceImporter;
                        if ((atPath != null) && atPath.GetPlatformTextureSettings(material.name, this.name, out this.maxTextureWidth, out this.maxTextureHeight, out this.m_TextureFormat, out this.m_LoadBehavior))
                        {
                            this.m_Overridden = true;
                            break;
                        }
                    }
                }
                if (!this.m_Overridden && (this.targets.Length > 0))
                {
                    SubstanceImporter importer2 = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(this.targets[0])) as SubstanceImporter;
                    if (importer2 != null)
                    {
                        importer2.GetPlatformTextureSettings((this.targets[0] as ProceduralMaterial).name, string.Empty, out this.maxTextureWidth, out this.maxTextureHeight, out this.m_TextureFormat, out this.m_LoadBehavior);
                    }
                }
            }

            public void Apply()
            {
                foreach (ProceduralMaterial material in this.targets)
                {
                    SubstanceImporter atPath = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(material)) as SubstanceImporter;
                    if (this.name != string.Empty)
                    {
                        if (this.m_Overridden)
                        {
                            atPath.SetPlatformTextureSettings(material.name, this.name, this.maxTextureWidth, this.maxTextureHeight, this.m_TextureFormat, this.m_LoadBehavior);
                        }
                        else
                        {
                            atPath.ClearPlatformTextureSettings(material.name, this.name);
                        }
                    }
                    else
                    {
                        atPath.SetPlatformTextureSettings(material.name, this.name, this.maxTextureWidth, this.maxTextureHeight, this.m_TextureFormat, this.m_LoadBehavior);
                    }
                }
            }

            public void ClearOverride(ProceduralMaterialInspector.ProceduralPlatformSetting master)
            {
                this.m_TextureFormat = master.textureFormat;
                this.maxTextureWidth = master.maxTextureWidth;
                this.maxTextureHeight = master.maxTextureHeight;
                this.m_LoadBehavior = master.m_LoadBehavior;
                this.m_Overridden = false;
            }

            public bool HasChanged()
            {
                ProceduralMaterialInspector.ProceduralPlatformSetting setting = new ProceduralMaterialInspector.ProceduralPlatformSetting(this.targets, this.name, this.target, null);
                return ((((setting.m_Overridden != this.m_Overridden) || (setting.maxTextureWidth != this.maxTextureWidth)) || ((setting.maxTextureHeight != this.maxTextureHeight) || (setting.textureFormat != this.textureFormat))) || (setting.m_LoadBehavior != this.m_LoadBehavior));
            }

            public void SetOverride(ProceduralMaterialInspector.ProceduralPlatformSetting master)
            {
                this.m_Overridden = true;
            }

            public bool isDefault
            {
                get
                {
                    return (this.name == string.Empty);
                }
            }

            public bool overridden
            {
                get
                {
                    return this.m_Overridden;
                }
            }

            public int textureFormat
            {
                get
                {
                    return this.m_TextureFormat;
                }
                set
                {
                    this.m_TextureFormat = value;
                }
            }
        }

        private class Styles
        {
            public GUIContent animatedContent = new GUIContent("Animation update rate", "Set the animation update rate in millisecond");
            public GUIContent[] coordNames = new GUIContent[] { new GUIContent("x"), new GUIContent("y"), new GUIContent("z"), new GUIContent("w") };
            public GUIContent defaultPlatform = EditorGUIUtility.TextContent("TextureImporter.Platforms.Default");
            public GUIContent generateAllOutputsContent = new GUIContent("Generate all outputs", "Force the generation of all substance's outputs.");
            public GUIContent hslContent = new GUIContent("HSL Adjustment", "Hue_Shift, Saturation, Luminosity");
            public GUIContent loadBehavior = new GUIContent("Load Behavior");
            public GUIContent randomizeButtonContent = new GUIContent("Randomize");
            public GUIContent randomSeedContent = new GUIContent("Random Seed", "$randomseed : the overall random aspect of the texture.");
            public GUIContent targetHeight = new GUIContent("Target Height");
            public GUIContent targetWidth = new GUIContent("Target Width");
            public GUIContent textureFormat = EditorGUIUtility.TextContent("TextureImporter.TextureFormat");
            public GUIContent[] textureFormatOptions = new GUIContent[] { EditorGUIUtility.TextContent("Compressed"), EditorGUIUtility.TextContent("RAW") };
        }
    }
}

